/**
 * #info
 *
 *@author   wuwg
 *@createTime   2018/05/16
 *@updateTime   2018/05/17
 *@description  markdown  component   markdown组件
 */

/**
 * #item
 *
 * @type        aty-markdown
 * @cn          markdown
 * @menu        其他
 * @stPlugin    true
 * @stContainer false
 * @mixins      [./components/components/other/markdown/mixins/markdown.js]
 */
import config from '../../../config/config.js'

// keydown Listen
import { keydownListen } from './md-tools/keydown-listen.js'
// extra-function
import {
  fullscreenchange,
  windowResize,
  scrollLink,
  insertTextAtCaret,
  getNavigation,
  insertTab,
  unInsertTab,
  insertOl,
  insertUl,
  insertEnter,
  removeLine,
  loadLink,
  loadScript,
  ImagePreviewListener
} from './md-tools/extra-function.js'
/**
 * @param  toolbarLeftClick      工具栏左侧按钮的点击
 * @param  toolbarLeftAddlink    工具栏左侧链接的点击
 */
import { toolbarLeftClick, toolbarLeftAddlink } from './md-operate/toolbar-left-click.js'
/**
 * @param  toolbarRightClick      工具栏右侧按钮的点击
 */
import { toolbarRightClick } from './md-operate/toolbar-right-click.js'
/**
 * @param  configOptions      配置
 */
import { configOptions } from './config/config-options.js'

// components
import autoTextarea from './components/auto-textarea/index.vue'
import mdToolbarLeft from './components/md-toolbar-left/index.vue'
import mdToolbarRight from './components/md-toolbar-right/index.vue'
// mixins
import markdown from './mixins/markdown.js'
// prefix
const prefixCls = config.prefix + '-mark-down'
//  module
export default {
  name: prefixCls,
  // mixins
  mixins: [markdown],
  components: {
    autoTextarea,
    mdToolbarLeft,
    mdToolbarRight
  },
  getMarkdownIt () {
    return this.mixins[0].data().markdownIt
  },
  //  props
  props: {
    /**
     * #property
     *
     * @name    scrollStyle
     * @cn      是否渲染滚动条样式
     * @type    boolean
     * @bind  must
     * @value    true
     * @description  是否渲染滚动条样式 (仅webkit内核有效)
     */
    scrollStyle: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    boxShadow
     * @cn      是否有阴影效果
     * @type    boolean
     * @bind  must
     * @value    true
     * @description  容器盒子，是否有阴影效果
     */
    boxShadow: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    fontSize
     * @cn      文本编辑区域字体大小
     * @type    string
     * @value    15px
     * @description   文本编辑区域字体大小
     */
    fontSize: {
      type: String,
      default: '15px'
    },
    /**
     * #property
     *
     * @name    value
     * @cn      初始value
     * @type    string
     * @description   文本编辑区域的初始value
     */
    value: {
      type: String,
      default: ''
    },
    /**
     * #property
     *
     * @name     language
     * @cn       语言
     * @type     list
     * @options     [zh-cn,en,fr,pt_BR]
     * @value     [zh-CN]
     * @description   编辑器内设文字语言，取值为 [zh-cn,en,fr,pt_BR]中的一个。
     */
    language: {
      type: String,
      default: 'zh-CN'
    },
    /**
     * #property
     *
     * @name    subfield
     * @cn      是否分栏显示
     * @type    boolean
     * @bind  must
     * @value    true
     * @description  是否分栏显示
     */
    subfield: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    navigation
     * @cn      是否开启标题导航
     * @type    boolean
     * @description  是否开启标题导航
     */
    navigation: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    defaultOpen
     * @cn      默认打开是预览模式还是编辑模式
     * @type     list
     * @options     [preview,edit]
     * @description  默认打开是预览模式还是编辑模式，取值为 [preview,edit] 中的一个
     */
    defaultOpen: {
      type: String,
      default: null
    },
    /**
     * #property
     *
     * @name    editable
     * @cn      是否开启可编辑
     * @type    boolean
     * @bind  must
     * @value    true
     * @description  是否开启可编辑
     */
    editable: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    toolbarsFlag
     * @cn      是否显示工具栏
     * @type    boolean
     * @bind  must
     * @value    true
     * @description  是否显示工具栏
     */
    toolbarsFlag: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    toolbars
     * @cn      工具栏配置
     * @type    object
     * @bind    must
     * @description  工具栏默认配置是所有，
     *   'toolbars': {
     * 'bold': true,  // 加粗
     * 'italic': true, // 倾斜
     * 'header': true, // 标题
     * 'underline': true, // 下划线
     * 'strikethrough': true, // 删除线;
     * 'mark': true, //  标记
     * 'superscript': true, // 上标
     * 'subscript': true, // 下标
     * 'quote': true, // 引用
     * 'ol': true, // 有列表
     * 'ul': true, //  无序列表
     * 'emoji':true,//  表情
     * 'link': true, // 连接
     * 'imagelink': true, // 图片连接
     * 'code': true, // 代码块
     * 'table': true, // 表格
     * 'undo': true, // 撤销
     * 'redo': true, // 重做
     * 'trash': true, // 删除
     * 'save': true, // 保存
     * 'alignleft': true, // 左对齐
     * 'aligncenter': true, // 居中对齐
     * 'alignright': true, // 右对齐
     * 'navigation': true, // 标题导航
     * 'subfield': true, // 分栏
     * 'fullscreen': true, // 全屏
     * 'readmodel': true, //  阅读模式
     * 'htmlcode': true, // 显示html代码
     * 'help': true, //  帮助
     * 'preview': true // 预览模式
     * }
     */
    toolbars: {
      type: Object,
      default () {
        return configOptions.toolbars
      }
    },
    /**
     * #property
     *
     * @name    codeStyle
     * @cn      markdown代码的样式
     * @type    string
     * @value    github
     * @description  markdown代码的样式,默认是 github的外观
     */
    codeStyle: {
      type: String,
      default () {
        return 'github'
      }
    },
    /**
     * #property
     *
     * @name    placeholder
     * @cn      值
     * @type    string
     * @description 占位文本,编辑区域为空时显示
     */
    placeholder: {
      type: String,
      default: null
    },
    externalLink: {
      type: [Object, Boolean],
      default: true
    },
    /**
     * #property
     *
     * @name    imageFilter
     * @cn      图片过滤的方法
     * @type    function
     * @bind    must
     * @description  图片过滤的方法，function 类型，返回 boolean值
     *   image_filter: function($files) {
     * console.log('image_filter files:', $files);
     * // console.log('here for you', $files);
     * return true;
     * }
     */
    imageFilter: {
      type: Function,
      default: null
    },
    /**
     * #property
     *
     * @name    imageClick
     * @cn      点击图片触发的回调函数
     * @type    function
     * @bind    must
     * @description  点击图片触发的回调函数 ，function 类型
     *    imageClick: function (file) {
     * console.log(file);
     * }
     */
    imageClick: {
      type: Function,
      default: null
    }
  },
  // data
  data () {
    return {
      s_right_click_menu_show: false,
      right_click_menu_top: 0,
      right_click_menu_left: 0,
      s_subfield: (() => {
        return this.subfield
      })(),
      s_autofocus: true,
      // 标题导航
      s_navigation: (() => {
        return this.navigation
      })(),
      s_scrollStyle: (() => {
        return this.scrollStyle
      })(), // props 是否渲染滚动条样式
      d_value: '', // props 文本内容
      d_render: '', // props 文本内容render
      s_preview_switch: (() => {
        let default_open_ = this.defaultOpen
        if (!default_open_) {
          default_open_ = this.subfield ? 'preview' : 'edit'
        }
        return default_open_ === 'preview'
      })(), // props true 展示编辑 false展示预览
      s_fullScreen: false, // 全屏编辑标志
      s_help: false, // markdown帮助
      s_html_code: false, // 分栏情况下查看html
      d_help: null,
      d_words: null,
      d_emoji: null, // 表情列表
      edit_scroll_height: -1,
      s_readmodel: false,
      s_table_enter: false, // 回车事件是否在表格中执行
      d_history: (() => {
        const temp_array = []
        temp_array.push(this.value)
        return temp_array
      })(), // 编辑记录
      d_history_index: 0, // 编辑记录索引
      currentTimeout: '',
      d_image_file: [],
      d_preview_imgsrc: null, // 图片预览地址
      s_external_link: {
        // markdown css
        markdown_css: function () {
          return 'https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/2.9.0/github-markdown.min.css'
        },
        //  hight light  js （高亮js）
        hljs_js: function () {
          return 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js'
        },
        //  hight light  js  language（高亮js的语言）
        hljs_lang: function (lang) {
          return 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/' + lang + '.min.js'
        },
        //  hight light  css （高亮css）
        hljs_css: function (css) {
          return 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/' + css + '.min.css'
        },
        //   katex  js   （自定义js）
        katex_js: function () {
          return 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.8.3/katex.min.js'
        },
        //   katex  css   （自定义css）
        katex_css: function () {
          return 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.8.3/katex.min.css'
        }
      },
      p_external_link: {}
    }
  },
  // watch
  watch: {
    d_value: function (val, oldVal) {
      this.iRender(val)
    },
    value: function (val, oldVal) {
      if (val !== this.d_value) {
        this.d_value = val
      }
    },
    subfield: function (val, oldVal) {
      this.s_subfield = val
    },
    d_history_index () {
      if (this.d_history_index > 20) {
        this.d_history.shift()
        this.d_history_index = this.d_history_index - 1
      }
      this.d_value = this.d_history[this.d_history_index]
    },
    language: function (val) {
      this.initLanguage()
    },
    editable: function () {
      this.editableTextarea()
    },
    defaultOpen: function (val) {
      let default_open_ = val
      if (!default_open_) {
        default_open_ = this.subfield ? 'preview' : 'edit'
      }
      return this.s_preview_switch = default_open_ === 'preview'
    },
    codeStyle: function (val) {
      this.codeStyleChange(val)
    }
  },
  // methods
  methods: {
    loadExternalLink (name, type, callback) {
      if (typeof this.p_external_link[name] !== 'function') {
        if (this.p_external_link[name] != false) {
          console.error('external_link.' + name, 'is not a function, if you want to disabled this error log, set external_link.' + name, 'to function or false')
        }
        return
      }
      // 加载css 和 js的函数
      var _obj = {
        css: loadLink,
        js: loadScript
      }
      if (_obj.hasOwnProperty(type)) {
        _obj[type](this.p_external_link[name](), callback)
      }
    },
    initExternalFuc () {
      var $vm = this
      var _external_ = ['markdown_css', 'hljs_js', 'hljs_css', 'hljs_lang', 'katex_js', 'katex_css']
      var _type_ = typeof $vm.externalLink
      var _is_object = (_type_ === 'object')
      var _is_boolean = (_type_ === 'boolean')
      for (var i = 0; i < _external_.length; i++) {
        if (
          (_is_boolean && !$vm.externalLink) ||
                    (_is_object && $vm.externalLink[_external_[i]] === false)) {
          $vm.p_external_link[_external_[i]] = false
        } else if (_is_object && typeof $vm.externalLink[_external_[i]] === 'function') {
          //  console.log( $vm.externalLink[_external_[i]]);
          $vm.p_external_link[_external_[i]] = $vm.externalLink[_external_[i]]
        } else {
          $vm.p_external_link[_external_[i]] = $vm.s_external_link[_external_[i]]
        }
      }
    },
    textAreaFocus () {
      this.$refs.vNoteTextarea.$refs.vTextarea.focus()
    },
    // @todo  拖拽
    $drag ($e) {
      var dataTransfer = $e.dataTransfer
      if (dataTransfer) {
        var files = dataTransfer.files
        if (files.length > 0) {
          $e.preventDefault()
          this.$refs.toolbar_left.$imgFilesAdd(files)
        }
      }
    },
    // @todo  粘贴，阻止默认粘贴事件
    $paste ($e) {
      var clipboardData = $e.clipboardData
      if (clipboardData) {
        var items = clipboardData.items
        if (!items) {
          return
        }
        var types = clipboardData.types || []
        var item = null
        for (var i = 0; i < types.length; i++) {
          if (types[i] === 'Files') {
            item = items[i]
            break
          }
        }
        if (item && item.kind === 'file') {
          /*
           * prevent filename being pasted parallel along
           * with the image pasting process
           */
          Artery.stopEvent($e)
          var oFile = item.getAsFile()
          // 添加文件
          this.$refs.toolbar_left.$imgFilesAdd([oFile])
        }
      }
    },
    $imgTouch (file) {
      var $vm = this
      // TODO 跳转到图片位置
    },
    $imgDel (file) {
      this.markdownIt.image_del(file[0])
      // 删除所有markdown中的图片
      const fileReg = file[2] ? file[2] : file[0]
      const reg = new RegExp(`\\!\\[${file[1]._name}\\]\\(${fileReg}\\)`, 'g')
      this.d_value = this.d_value.replace(reg, '')
      this.iRender()
      /**
       * #event
       *
       * @name    img-del
       * @param   fileReg  当前的值
       * @body
       * @description  删除所有markdown中的图片是触发
       */
      this.$emit('img-del', fileReg)
    },
    // @todo  添加图片
    $imgAdd (pos, $file, isinsert) {
      if (isinsert === undefined) {
        isinsert = true
      }
      var $vm = this
      if (this.__rFilter == null) {
        // this.__rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
        this.__rFilter = /^image\//i
      }
      this.__oFReader = new FileReader()
      this.__oFReader.onload = function (oFREvent) {
        $vm.markdownIt.image_add(pos, oFREvent.target.result)
        $file.miniurl = oFREvent.target.result
        if (isinsert === true) {
          // 去除特殊字符
          $file._name = $file.name.replace(/[\[\]\(\)\+\{\}&\|\\\*^%$#@\-]/g, '')
          $vm.insertText($vm.getTextareaDom(),
            {
              prefix: '![' + $file._name + '](' + pos + ')',
              subfix: '',
              str: ''
            })
          // 添加图片
          $vm.$nextTick(function () {
            /**
             * #event
             *
             * @name    img-add
             * @param   pos  位置
             * @param   file  文件
             * @body
             * @description  添加图片时触发
             */
            $vm.$emit('img-add', pos, $file)
          })
        }
      }
      if ($file) {
        var oFile = $file
        if (this.__rFilter.test(oFile.type)) {
          this.__oFReader.readAsDataURL(oFile)
        }
      }
    },
    $imgUpdateByUrl (pos, url) {
      var $vm = this
      this.markdownIt.image_add(pos, url)
      this.$nextTick(function () {
        $vm.d_render = this.markdownIt.render(this.d_value)
      })
    },
    $imgAddByUrl (pos, url) {
      if (this.$refs.toolbar_left.$imgAddByUrl(pos, url)) {
        this.$imgUpdateByUrl(pos, url)
        return true
      }
      return false
    },
    $img2Url (fileIndex, url) {
      // x.replace(/(\[[^\[]*?\](?=\())\(\s*(\.\/2)\s*\)/g, "$1(http://path/to/png.png)")
      var reg_str = '/(!\\[\[^\\[\]*?\\]\(?=\\(\)\)\\(\\s*\(' + fileIndex + '\)\\s*\\)/g'
      var reg = eval(reg_str)
      this.d_value = this.d_value.replace(reg, '$1(' + url + ')')
      this.$refs.toolbar_left.$changeUrl(fileIndex, url)
      this.iRender()
    },
    $imglst2Url (imglst) {
      if (imglst instanceof Array) {
        for (var i = 0; i < imglst.length; i++) {
          this.$img2Url(imglst[i][0], imglst[i][1])
        }
      }
    },
    toolbarLeftClick (_type, arg) {
      toolbarLeftClick(_type, arg, this)
    },
    toolbarLeftAddlink (_type, text, link) {
      toolbarLeftAddlink(_type, text, link, this)
    },
    toolbarRightClick (_type) {
      toolbarRightClick(_type, this)
    },
    getNavigation ($vm, full) {
      return getNavigation($vm, full)
    },
    /*
     * @event
     * 修改数据触发 （val ， val_render）
     */
    change (val, render) {
      /**
       * #event
       *
       * @name    change
       * @param   val  当前的值
       * @param   render    渲染后的结果
       * @body
       * @description  修改数据触发
       */
      this.$emit('change', val, render)
    },
    // 切换全屏触发 （status , val）
    fullscreen (status, val) {
      /**
       * #event
       *
       * @name    full-screen
       * @param   status  是否是全屏
       * @param   val     当前的值
       * @body
       * @description  切换全屏触发
       */
      this.$emit('full-screen', status, val)
    },
    // 打开阅读模式触发（status , val）
    readmodel (status, val) {
      /**
       * #event
       *
       * @name    read-model
       * @param   status  是否阅读模式
       * @param   val     当前的值
       * @body
       * @description  打开阅读模式触发
       */
      this.$emit('read-model', status, val)
    },
    // 切换阅读编辑触发 （status , val）
    previewtoggle (status, val) {
      /**
       * #event
       *
       * @name    preview-toggle
       * @param   status  是编辑模式|预览模式
       * @param   val     当前的值
       * @body
       * @description  切换阅读编辑触发
       */
      this.$emit('preview-toggle', status, val)
    },
    // 切换分栏触发 （status , val）
    subfieldtoggle (status, val) {
      /**
       * #event
       *
       * @name    subfield-toggle
       * @param   status  是否是分栏
       * @param   val     当前的值
       * @body
       * @description  切换分栏触发
       */
      this.$emit('subfield-toggle', status, val)
    },
    // 切换htmlcode触发 （status , val）
    htmlcode (status, val) {
      /**
       * #event
       *
       * @name    html-code
       * @param   status  是否是代码模式
       * @param   val     当前的值
       * @body
       * @description      切换htmlcode触发
       */
      this.$emit('html-code', status, val)
    },
    // 打开 , 关闭 help触发 （status , val）
    helptoggle (status, val) {
      /**
       * #event
       *
       * @name    help-toggle
       * @param   status  help状态
       * @param   val     当前的值
       * @body
       * @description      打开 , 关闭 help触发
       */
      this.$emit('help-toggle', status, val)
    },
    // 监听ctrl + s
    save (val, render) {
      /**
       * #event
       *
       * @name    save
       * @param   val       当前的值
       * @param   render     渲染后的值
       * @body
       * @description  监听ctrl + s，按下ctrl + s || 点击保存触发
       */
      this.$emit('save', val, render)
    },
    // 导航栏切换
    navigationtoggle (status, val) {
      /**
       * #event
       *
       * @name    navigation-toggle
       * @param   status  导航栏切换状态
       * @param   val     当前的值
       * @body
       * @description     导航栏切换触发
       */
      this.$emit('navigation-toggle', status, val)
    },
    $toolbar_right_read_change_status () {
      this.s_readmodel = !this.s_readmodel
      if (this.readmodel) {
        this.readmodel(this.s_readmodel, this.d_value)
      }
      if (this.s_readmodel && this.toolbars.navigation) {
        this.getNavigation(this, true)
      }
    },
    /*
     * ---------------------------------------
     * 滚动条联动
     */
    $v_edit_scroll ($event) {
      scrollLink($event, this)
    },
    // 获取textarea dom节点
    getTextareaDom () {
      return this.$refs.vNoteTextarea.$refs.vTextarea
    },
    // 工具栏插入内容
    insertText (obj, { prefix, subfix, str, type }) {
      // if (this.s_preview_switch) {
      insertTextAtCaret(obj, { prefix, subfix, str, type }, this)
    },
    insertTab () {
      insertTab(this)
    },
    insertOl () {
      insertOl(this)
    },
    removeLine () {
      removeLine(this)
    },
    insertUl () {
      insertUl(this)
    },
    unInsertTab () {
      unInsertTab(this)
    },
    insertEnter (event) {
      insertEnter(this, event)
    },
    saveHistory () {
      this.d_history.splice(this.d_history_index + 1, this.d_history.length)
      this.d_history.push(this.d_value)
      this.d_history_index = this.d_history.length - 1
    },
    initLanguage () {
      const lang = configOptions.langList.indexOf(this.language) >= 0 ? this.language : 'zh-CN'
      var $vm = this
      if (!Artery.isServer) {
      $vm.$render(configOptions[`help_${lang}`], function (res) {
        $vm.d_help = res
      })
      }
      this.d_words = configOptions[`words_${lang}`]
    },
    // 编辑开关
    editableTextarea () {
      const text_dom = this.$refs.vNoteTextarea.$refs.vTextarea
      if (this.editable) {
        text_dom.removeAttribute('disabled')
      } else {
        text_dom.setAttribute('disabled', 'disabled')
      }
    },
    codeStyleChange (val, isInit) {
      isInit = isInit || false
      if (typeof this.p_external_link.hljs_css !== 'function') {
        if (this.p_external_link.hljs_css != false) { console.error('external_link.hljs_css is not a function, if you want to disabled this error log, set external_link.hljs_css to function or false') }
        return
      }
      var url = this.p_external_link.hljs_css(val)
      if (url.length === 0 && isInit) {
        console.warn('hljs color scheme', val, 'do not exist, loading default github')
        url = this.p_external_link.hljs_css('github')
      }
      if (url.length > 0) {
        loadLink(url)
      } else {
        console.warn('hljs color scheme', val, 'do not exist, hljs color scheme will not change')
      }
    },
    iRender () {
      var $vm = this
      $vm.$render($vm.d_value, function (res) {
        // render
        $vm.d_render = res
        // change回调
        if ($vm.change) {
          $vm.change($vm.d_value, $vm.d_render)
        }
        // 改变标题导航
        if ($vm.s_navigation) {
          getNavigation($vm, false)
        }
        $vm.$emit('input', $vm.d_value)
        // 塞入编辑记录数组
        if ($vm.d_value === $vm.d_history[$vm.d_history_index]) {
          return
        }
        window.clearTimeout($vm.currentTimeout)
        $vm.currentTimeout = setTimeout(() => {
          $vm.saveHistory()
        }, 500)
      })
    },

    /**
     * #method
     *
     * @name    getRenderContent
     * @returns {String} 渲染后的html
     * @description  获取render后的html内容
     */
    getRenderContent () {
      var $vm = this
      return $vm.d_render
    },
    // 清空上一步 下一步缓存
    $emptyHistory () {
      this.d_history = [this.d_value] // 编辑记录
      this.d_history_index = 0 // 编辑记录索引
    },
    // 初始化表情
    initEmoji () {
      this.d_emoji = configOptions.emoji
    }
  },

  created () {
    var $vm = this

    $vm.initExternalFuc()
    // 初始化语言
    this.initLanguage()
    // 初始化表情
    this.initEmoji()
    if (!Artery.isServer) {
    this.$nextTick(() => {
      // 初始化Textarea编辑开关
      this.editableTextarea()
    })
    }
  },
  mounted () {
    var $vm = this
    this.$el.addEventListener('paste', function (e) {
      $vm.$paste(e)
    })
    this.$el.addEventListener('drop', function (e) {
      $vm.$drag(e)
    })
    // 浏览器siz大小
    /* windowResize(this); */
    keydownListen(this)
    // 图片预览事件监听
    ImagePreviewListener(this)
    // fullscreen事件
    fullscreenchange(this)
    this.d_value = this.value
    // 将help添加到末尾
    document.body.appendChild(this.$refs.help)

    // 加载css
    $vm.loadExternalLink('markdown_css', 'css');
    $vm.loadExternalLink('katex_css', 'css');

    $vm.loadExternalLink('katex_js', 'js', function () {
      $vm.initLanguage();
      $vm.iRender();
    });
    $vm.loadExternalLink('hljs_js', 'js', function () {
      $vm.initLanguage();
      $vm.iRender();
    });
    // 默认代码模式
    $vm.codeStyleChange($vm.codeStyle, true)

    // 触发 ready事件
    this.$emit('ready', $vm)
  },
  beforeDestroy () {
    document.body.removeChild(this.$refs.help)
  }
}
